﻿using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Imaging;


namespace Reuse.WS.Common {
	public class ImageEx : DependencyObject, INotifyPropertyChanged {
		public static readonly DependencyProperty LoadingImageProperty = 
			DependencyProperty.RegisterAttached( "LoadingImage", typeof( string ), typeof( ImageEx ), null );
		public static readonly DependencyProperty ImageProperty =
			DependencyProperty.RegisterAttached( "Image", typeof( string ), typeof( ImageEx ), new PropertyMetadata( null, OnImageChanged ) );

		public event PropertyChangedEventHandler PropertyChanged;
		void FirePropertyChanged( string property ) {
			if ( this.PropertyChanged != null ) {
				this.PropertyChanged( this, new PropertyChangedEventArgs( property ) );
			}
		}

		private static async void OnImageChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) {
			( (ImageEx)d ).Load();
		}

		public HttpClient client { get; set; }
		public bool HasLoaded { get; set; }

		BitmapImage _image;
		public BitmapImage ImageBitmap {
			get {
				return ( _image );
			}
			private set {
				this._image = value;
				this.FirePropertyChanged( "ImageBitmap" );
			}
		}

		public ImageEx() {
			if ( !HasLoaded ) {
				client = new HttpClient();

			}
		}

		public void Load() {
			LoadImage();
		}

		public async void LoadImage() {

			if ( String.IsNullOrEmpty( ImageEx.GetImage( this ) ) ) return;

			ImageBitmap = new BitmapImage( new Uri( String.Concat( "ms-appx:///", ImageEx.GetLoadingImage( this ) ) ) );

			//img.Source = new BitmapImage( new Uri( ImageEx.GetImage( this ), UriKind.Absolute ) );
			//return;

			try {
				var ras = new InMemoryRandomAccessStream();
				var memoryStream = new MemoryStream();
				var stream = await client.GetStreamAsync( ImageEx.GetImage( this ) );

				await stream.CopyToAsync( memoryStream );
				var output = ras.GetOutputStreamAt( 0 );
				var dw = new DataWriter( output );
				var task = new Task( () => dw.WriteBytes( memoryStream.ToArray() ) );
				task.Start();

				await task;
				await dw.StoreAsync();

				await output.FlushAsync();


				//	var buffer = new byte[500];
				//	int read;
				//	do {
				//		read = await stream.ReadAsync( buffer, 0, buffer.Length );
				//		await ras.WriteAsync( buffer.AsBuffer() );
				//	} while ( read != 0 );
				//	await ras.FlushAsync();
				//	ras.Seek( 0 );


				var imgStream = new BitmapImage();
				await imgStream.SetSourceAsync( ras );
				ImageBitmap = imgStream;

				HasLoaded = true;


			} catch ( Exception ex ) {

			}

		}

		[SuppressMessage( "Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Standard pattern." )]
		public static string GetLoadingImage( DependencyObject source ) {
			return (string)source.GetValue( LoadingImageProperty );
		}

		[SuppressMessage( "Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Standard pattern." )]
		public static void SetLoadingImage( DependencyObject source, string value ) {
			source.SetValue( LoadingImageProperty, value );
		}

		public static string GetImage( DependencyObject obj ) {
			return (string)obj.GetValue( ImageProperty );
		}

		public static void SetImage( DependencyObject obj, string value ) {
			obj.SetValue( ImageProperty, value );
		}
	}
}
